package main.java.com.waylau.netty.demo.tcppackage;

import java.io.UnsupportedEncodingException;
import java.util.Date;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;

/**
 * 作者  Administrator
 * 时间  2017/6/26 17:50
 * 文件  nettydemo
 * 描述
 */
public class TimeServer {
	public void bind(int port) throws InterruptedException {
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		try {
			ServerBootstrap b = new ServerBootstrap();
			b.group(bossGroup, workerGroup)
					.channel(NioServerSocketChannel.class)
					.option(ChannelOption.SO_BACKLOG, 1024)//配置buff 的长度
					.childHandler(new ChildChannelHander());

			ChannelFuture f = b.bind(port).sync();
			f.channel().closeFuture().sync();

		} finally {
			bossGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
		}

	}

	private class ChildChannelHander extends ChannelInitializer<SocketChannel> {

		@Override
		protected void initChannel(SocketChannel arg0) throws Exception {
			arg0.pipeline().addLast(new LineBasedFrameDecoder(20));
			arg0.pipeline().addLast(new StringDecoder());
			arg0.pipeline().addLast(new TimeServerHandler());
		}
	}

	/**
	 * @param args
	 * @throws InterruptedException
	 */
	public static void main(String[] args) throws InterruptedException {
		int port = 8080;
		if (args != null && args.length > 0) {
			port = Integer.valueOf(args[0]);
		}
		new TimeServer().bind(port);
	}

	class TimeServerHandler extends ChannelInboundHandlerAdapter {

		private int counter;


		/**
		 * @param ctx
		 * @param msg 实际上没成功拆一个数据包,才会调用一次channelRead
		 *            而不是每读 一次TCP 缓存
		 * @throws UnsupportedEncodingException
		 * 那边发送了一百个包，但是这边只接收了两次
		 * 验证：是不是 满了后才会调用 channelRead
		 * 1024+956
		 */
		@Override
		public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException {
			/*ByteBuf buf = (ByteBuf) msg;
			byte[] req = new byte[buf.readableBytes()];
			buf.readBytes(req);*/
			String body = (String) msg;
			counter++;
			System.out.println("channelRead数据长度："+body.getBytes().length);
			System.out.println("数据内容："+body);
//			String body = new String(req, "UTF-8").substring(0, req.length - System.getProperty("line.separator").length());
         /*   String body = (String) msg;
			System.out.println("The time server receive order :" + body + " ; the counter is:" + ++counter);

			String currentTime = "Query time order".equalsIgnoreCase(body) ? new Date(System.currentTimeMillis()).toString() : "Bad order";
			currentTime = currentTime + System.getProperty("line.separator");
			ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());
			ctx.writeAndFlush(resp);*/
		}

		@Override
		public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
			super.channelReadComplete(ctx);
			System.out.println("channelReadComplete"+counter);
		}

		@Override
		public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
			super.exceptionCaught(ctx, cause);
			ctx.close();
		}
	}
}
